<?php

namespace app\common\model;

use app\common\controller\AliSMSController;
use app\lib\exception\BaseException;
use Cache;
use think\Model;

class User extends Model
{
    //自动写入时间
    protected $autoWriteTimestamp = true;

    //发送验证码
    public function sendCode()
    {

        //获取手机号码
        $phone = request()->param('phone');

        //存储验证
        if (Cache::get($phone)) {
            throw new BaseException(['code' => 200, 'msg' => '你操作太频繁了', 'errCode' => 30001]);
        }

        // 生成验证码
        $code = random_int(1000, 9999);

        //发送验证码
        if (!config("api.aliSMS.isopen")) {
            Cache::set($phone, $code, config('api.aliSMS.expire'));
            throw new BaseException(['code' => 200, 'msg' => '验证码:' . $code, 'errCode' => 30005]);
        }

        $res = AlismsController::SendSMS($phone, $code);

        if ($res['Code'] != 'OK') {
            //发送失败
            throw new BaseException(['code' => 200, 'msg' => '发送失败', 'errCode' => 30004]);
        }

        return Cache::set($phone, $code, config('api.alisms.expire'));
    }

    // 绑定用户信息表
    public function userinfo()
    {
        return $this->hasOne('Userinfo');
    }

    // 判断用户是否存在
    public function isExist($arr = [])
    {
        if (!is_array($arr)) {
            return false;
        }

        if (array_key_exists('phone', $arr)) {
            return $this->where('phone', $arr['phone'])->find();
        }
        if (array_key_exists('id', $arr)) {
            return $this->where('id', $arr['id'])->find();
        }
        if (array_key_exists('email', $arr)) {
            return $this->where('email', $arr['email'])->find();
        }
        if (array_key_exists('username', $arr)) {
            return $this->where('username', $arr['username'])->find();
        }

        return false;
    }

    //手机登录
    public function phoneLogin()
    {
        // 获取所有参数
        $param = request()->param();

        // 验证用户是否存在
        $user = $this->isExist(['phone' => $param['phone']]);

        // 用户不存在 直接注册
        if (!$user) {
            // 用户主表
            $user = self::create([
                'username' => $param['phone'],
                'phone' => $param['phone'],
                'password' => password_hash($param['phone'], PASSWORD_DEFAULT),
            ]);

            // 在用户信息表创建对应的记录 用户存放用户其他信息
            $user->userinfo()->create(['user_id' => $user->id]);
            return $this->CreateSaveToken($user->toArray());
        }

        // 用户是否被禁用
        $this->checkStatus($user->toArray());

        // 登陆成功 返回token
        return $this->CreateSaveToken($user->toArray());
    }

    //生成 并保存 token
    public function CreateSaveToken($arr = [])
    {
        // 生成Token
        $token = sha1(md5(uniqid(md5(microtime(true)), true)));
        $arr['token'] = $token;

        // 登陆过期时间
        // $expire = array_key_exists('expires_in', $arr)? $arr['expires_in']:config('api.token_expire');

        // 保存到缓存中
        if (!Cache::set($token, $arr, config('api.token_expire'))) {
            throw new BaseException();
        }

        // 返回token
        return $token;
    }

    // 用户是否被禁用
    public function checkStatus($arr)
    {
        $status = $arr['status'];
        if ($status == 0) {
            throw new BaseException(['code' => 200, 'msg' => '该用户已经被禁用', 'errCode' => 20001]);
        }

        return $arr;
    }

    // 账号登陆
    public function login()
    {
        // 获取所有参数
        $param = request()->param();

        // 验证用户是否存在
        $user = $this->isExist($this->filterUserData($param['username']));

        // 用户不存在
        if (!$user) {
            throw new BaseException(['code' => 200, 'msg' => '昵称/邮箱/手机号错误', 'errCode' => 20000]);
        }

        // 用户是否被禁用
        $this->checkStatus($user->toArray());

        // 验证密码
        $this->checkPassword($param['password'], $user->password);

        // 登陆成功 生成token
        return $this->CreateSaveToken($user->toArray());
    }

    // 验证用户名是什么格式，昵称/邮箱/手机号
    public function filterUserData($data)
    {
        $arr = [];
        // 验证是否是手机号码
        if (preg_match('^1(3|4|5|7|8)[0-9]\d{8}$^', $data)) {
            $arr['phone'] = $data;
            return $arr;
        }
        // 验证是否是邮箱
        if (preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/', $data)) {
            $arr['email'] = $data;
            return $arr;
        }
        $arr['username'] = $data;
        return $arr;
    }

    // 验证密码
    public function checkPassword($password, $hash)
    {
        if (!$hash) {
            throw new BaseException(['code' => 200, 'msg' => '密码错误', 'errorCode' => 20002]);
        }

        // 密码错误
        if (!password_verify($password, $hash)) {
            throw new BaseException(['code' => 200, 'msg' => '密码错误', 'errorCode' => 20002]);
        }

        return true;
    }
}
